package {
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import com.passioneffect.adapter.ContentMovieClipAdapter;
	import com.passioneffect.collection.Collection;
	import com.passioneffect.collection.Iterator;
	import com.passioneffect.display.Component;
	import com.passioneffect.layout.Layout;	

	/**
	 * @author Passion Effect
	 */
	public class CarouselLayout extends Layout {
		public var interAngle : Number;
		private var comp : SuperCarouselV2;
		private var drawFunction:Function;
		private var interFunction:Function;
		
		public function CarouselLayout(component : SuperCarouselV2) {
			super(component);
			comp = SuperCarouselV2(component);
			
			drawFunction=carouselDraw;
			interFunction=carouselInterFunction;
			
			//scrollValue.x is in rad
			//scrollValueX is in angle
			
			if(items.getLength()) {
				preset();
			}
		}

		//on init items var , run after items added and before layout them.
		override public function preset() : void {
			
			interAngle = 360 / items.getLength();
		}

		public function flowDraw(index : int) : Point {
			var tx : Number = 0;
			var ty : Number = 0;
			
			var offset : Number;
			
			tx = index * unselectedX + spacing-scrollValueX;
			ty = component.compLengthY/2-component.unselectedY/2;
			
			var i : int;
			
			for(var adapter:Object in layoutValue) {
				
				i = ContentMovieClipAdapter(adapter).getIndex();
				//remember all are based on (0,0) !!!
				//can set start x for scrolling
				if(index > i) {
					offset = layoutValue[adapter].xLength - unselectedX;
					tx += offset;
				}
			}
		
			if(direction == "horizontal") {
				return new Point(tx, ty);
			}else {
				return new Point(ty, tx);
			}
		}

		override public function draw(index : int) : Point {
			return drawFunction(index);
		}
		
		public function carouselDraw(index:int):Point{
			
			var angleRad : Number = (interAngle * index) * Math.PI / 180;
			var tScroll : Number;
			
			var tx : Number;
			var ty : Number;
			var c:Object=getLayoutSize(index);
			
			if(direction == "horizontal") {
				tScroll = angleRad - scrollValue.x;
				
				tx = centerX + comp.radiusX * Math.sin(tScroll)+comp.centerX;
				ty = centerY + comp.radiusY * Math.cos(tScroll)+comp.centerY;
				
			}else if(direction == "vertical") {
				tScroll = angleRad - scrollValue.x;
				
				tx = centerX - comp.radiusY * Math.cos(tScroll)+comp.centerX;
				ty = centerY + comp.radiusX * Math.sin(tScroll)+comp.centerY;
			}else {
				return null;
			}
			
			var scale : Number = getInterValue(index).scale;

			return new Point(tx,ty);
		}
		
		override public function resetDepths(viewList : Collection) : void {
			if(type=="flow")return;
			
			var depthList : Collection = viewList.clone();
			
			var itr : Iterator = depthList.iterator();
			var depths : Array = [];
			var highDepths : Array = [];
			var mc : MovieClip;
			
			while(itr.hasNext()) {
				var item : ContentMovieClipAdapter = ContentMovieClipAdapter(itr.next());
				var c : Object = layoutValue[item];
				if(c && c.depthIndex) {
					highDepths[c.depthIndex] = item.getMovieClip();
				}else {
					mc = item.getMovieClip();
					var index : int = item.getIndex();
					var depth : Number = getInterValue(index).depth;
					depths.push({mc:mc, depth:depth});
				}
			}
			
			if(comp.centerItems){
				var centerItem:DisplayObject;
				
				itr=comp.centerItems.iterator();
				while(itr.hasNext()){
					centerItem=DisplayObject(itr.next());
					depths.push({mc:centerItem,depth:0});
				}
			}
			
			depths.sortOn("depth", Array.NUMERIC);
			for(var i : int = 0;i < depths.length;i++) {
				mc = MovieClip(depths[i].mc);
				component.addChildAt(mc, i);
				if(mc.tooltip)mc.tooltip.updatePosition();
			}
			
			for(var j : int = highDepths.length - 1;j > 0;j--) {
				mc = MovieClip(highDepths[j]);
				mc.parent.addChild(mc);
			}
		}

		override public function getInterValue(index : int) : Object {
			return interFunction(index);
		}
		
		private function flowInterFunction(index:int) : Object {
			return null;
		}

		private function carouselInterFunction(index:int):Object{
			var angleRad : Number = (interAngle * index) * Math.PI / 180;
			
			var scale : Number;
			var depth : Number;
			var blur : Number;
			var brightness : Number;
			
			depth = Math.cos(angleRad - scrollValue.x);
			var depth2 : Number = (depth + 1) / 2;
			
			scale = comp.minScale + (comp.maxScale - comp.minScale) * depth2;
			blur = comp.blurScale * (1 - depth2);
			brightness = comp.minBrightness + (comp.maxBrightness - comp.minBrightness) * depth2;
			
			return {brightness:brightness, scale:scale, depth:depth, blur:blur};
		}

		override public function set scrollValueX(v : Number) : void {
			scrollValue.x = (v * Math.PI) / 180;
		}

		override public function get scrollValueX() : Number {
			return scrollValue.x * 180 / Math.PI;
		}

		override public function set scrollValueY(v : Number) : void {
			//	if(v > maxScrollY)v = maxScrollY;else if(v < minScrollY)v = minScrollY;
			comp.radiusY=v;
		}

		override public function get scrollValueY() : Number {
			return comp.radiusY;
		}

		override public function getScrollPercentValue(percent : Number,atPercent : Number = NaN) : Point {
			return new Point(percent * 360, 0);
		}

		override public function getScrollLengthValue(length : Number) : Point {
			return new Point(length, length);
		}

		override public function getScrollValue(index : int,atItemPercent : Number,atPercent : Number) : * {
			var angle : Number = interAngle * index;
			var size:Object=getLayoutSize(index);
			
			var d : Number = (angle - scrollValueX);
			
			while(d > 180 || d < -180) {
				if(d >= 180) {
					angle -= 360;
				}else if(d < -180) {
					angle += 360;
				}
				d = angle - scrollValueX;
			}
			
			
			return new Point(angle, scrollValueY);
		}

		override public function get scrollPercentX() : Number {
			
			var d : Number = scrollValueX;
			if(d < 0 || d > 360) {
				d = d % 360;
				if(d < 0) {
					d += 360;
				}
			}
			return d / getTotalLengthX();
		}

		public function get currentAngle() : Number {
			return 0;
		}

		public function get centerX() : Number {
			return component.compWidth / 2;
		}

		public function get centerY() : Number {
			return component.compHeight / 2;
		}

		override public function getTotalLength() : Number {
			return 360;
		}

		override public function getTotalLengthX() : Number {
			return 360;
		}
	}
}
